﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Text;

namespace DotNETX.Authentication.Db
{
    public abstract class DbUserManager : IUserManager
    {
        // 附加筛选条件
        public string UserFilter { get; set; }

        public virtual UserIdentifier Find(string loginid)
        {
            if (!TryOpenConnection(Connection)) return null;

            IDbCommand cmd = Connection.CreateCommand();
            string paramExpression = null;
            paramExpression = CreateParam(cmd, "p_LoginId", loginid);
            cmd.CommandText = string.Format("select {1} as c_LoginId, {2} as c_Password, {3} as c_UniqueId from {0} where {1}={4}", TableName, LoginIdColumn, PasswordColumn, UniqueIdColumn, paramExpression);
            if (UserFilter != null) cmd.CommandText += string.Format(" and ({0})", UserFilter);
            try
            {
                using (IDataReader reader = cmd.ExecuteReader())
                {
                    if (reader.Read())
                    {
                        return new UserIdentifier() { LoginId = reader.GetValue(0).ToString(), Password = reader.GetValue(1).ToString(), UniqueId = reader.GetValue(2) };
                    }
                    else
                    {
                        return null;
                    }
                }
            }
            catch
            {
                return null;
            }
            finally
            {
                Connection.Close();
            }
        }

        public bool SetPassword(string loginid, string pwd)
        {
            if (!TryOpenConnection(Connection)) return false;

            IDbCommand cmd = Connection.CreateCommand();
            string paramLidExpression = null;
            string paramPwdExpression = null;
            paramLidExpression = CreateParam(cmd, "p_LoginId", loginid);
            paramPwdExpression = CreateParam(cmd, "p_Password", pwd);

            cmd.CommandText = string.Format("update {0} set {2} = {5} where {1}={4}", TableName, LoginIdColumn, PasswordColumn, UniqueIdColumn, paramLidExpression, paramPwdExpression);
            if (UserFilter != null) cmd.CommandText += string.Format(" and ({0})", UserFilter);
            try
            {
                if (cmd.ExecuteNonQuery() == 1)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch
            {
                return false;
            }
            finally
            {
                Connection.Close();
            }
        }

        public abstract string CreateParam(IDbCommand cmd, string paramName, object paramValue);
        public virtual bool TryOpenConnection(IDbConnection connection)
        {
            if (connection == null) return false;
            try
            {
                if (connection.State == ConnectionState.Closed)
                {
                    connection.Open();
                }
                else if (connection.State == ConnectionState.Broken)
                {
                    connection.Close();
                    connection.Open();
                }
                return true;
            }
            catch (System.Exception ex)
            {
                return false;
            }
        }

        public IDbConnection Connection { get; set; }

        public string TableName { get; set; }
        public string LoginIdColumn { get; set; }
        public string PasswordColumn { get; set; }
        public string UniqueIdColumn { get; set; }
    }
}
